package com.blog.cloud.auth.oauth;

import com.xkcoding.justauth.support.cache.RedisStateCache;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.cache.AuthDefaultStateCache;
import me.zhyd.oauth.cache.AuthStateCache;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Slf4j
public class AuthStateCacheConfiguration {

    @ConditionalOnProperty(
            name = {"justauth.cache.type"},
            havingValue = "custom"
    )
    static class Custom {
        Custom() {
        }

        @Bean
        @ConditionalOnMissingBean({AuthStateCache.class})
        public AuthStateCache authStateCache() {
            log.error("请自行实现 me.zhyd.oauth.cache.AuthStateCache");
            throw new RuntimeException();
        }

        static {
            log.debug("JustAuth 使用 自定义缓存存储 state 数据");
        }
    }

    @ConditionalOnMissingBean({AuthStateCache.class})
    @ConditionalOnProperty(
            name = {"justauth.cache.type"},
            havingValue = "default",
            matchIfMissing = true
    )
    static class Default {
        Default() {
        }

        @Bean
        public AuthStateCache authStateCache() {
            return AuthDefaultStateCache.INSTANCE;
        }

        static {
            log.debug("JustAuth 使用 默认缓存存储 state 数据");
        }
    }

    @ConditionalOnClass({RedisTemplate.class})
    @ConditionalOnMissingBean({AuthStateCache.class})
    @AutoConfigureBefore({RedisAutoConfiguration.class})
    @ConditionalOnProperty(
            name = {"justauth.cache.type"},
            havingValue = "redis",
            matchIfMissing = true
    )
    static class Redis {
        Redis() {
        }

        @Bean(
                name = {"justAuthRedisCacheTemplate"}
        )
        public RedisTemplate<String, String> justAuthRedisCacheTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, String> template = new RedisTemplate();
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }

        @Bean
        public AuthStateCache authStateCache(RedisTemplate<String, String> justAuthRedisCacheTemplate, com.xkcoding.justauth.autoconfigure.JustAuthProperties justAuthProperties) {
            return new RedisStateCache(justAuthRedisCacheTemplate, justAuthProperties.getCache());
        }

        static {
            log.debug("JustAuth 使用 Redis 缓存存储 state 数据");
        }
    }
}
